package com.pai4j.zwiki.service;

import com.pai4j.zwiki.domain.entity.CodeStructureEntity;
import com.pai4j.zwiki.domain.entity.QaIndexEntity;
import com.pai4j.zwiki.dto.QaResponse;
import com.pai4j.zwiki.repository.CodeStructureRepository;
import com.pai4j.zwiki.repository.QaIndexRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 问答服务
 * 基于代码索引和LLM提供交互式问答
 *
 * @author pai4j
 * @since 2025-10-12
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QaService {

    private final QaIndexRepository qaIndexRepository;
    private final CodeStructureRepository codeStructureRepository;
    private final LLMService llmService;

    /**
     * 回答用户问题（优化版 - 改进参数校验和错误处理）
     *
     * @param taskId   任务ID
     * @param question 用户问题
     * @return 回答
     */
    public QaResponse answerQuestion(String taskId, String question) {
        log.info("处理问答请求, 任务ID: {}, 问题: {}", taskId, question);
        
        // 参数校验
        if (taskId == null || taskId.trim().isEmpty()) {
            log.warn("任务ID为空");
            return QaResponse.builder()
                    .answer("任务ID不能为空")
                    .relatedCodeSnippets(new ArrayList<>())
                    .conversationId(taskId)
                    .build();
        }
        
        if (question == null || question.trim().isEmpty()) {
            log.warn("用户问题为空");
            return QaResponse.builder()
                    .answer("请输入您的问题")
                    .relatedCodeSnippets(new ArrayList<>())
                    .conversationId(taskId)
                    .build();
        }

        try {
            // 1. 检索相关代码片段
            List<QaResponse.CodeSnippet> relatedSnippets = searchRelatedCode(taskId, question);

            // 2. 构建上下文（添加 null 检查）
            List<String> codeContext = relatedSnippets.stream()
                    .filter(Objects::nonNull)
                    .map(QaResponse.CodeSnippet::getContent)
                    .filter(content -> content != null && !content.trim().isEmpty())
                    .collect(Collectors.toList());

            // 3. 使用LLM生成回答
            String answer = llmService.answerQuestion(question, codeContext);

            return QaResponse.builder()
                    .answer(answer)
                    .relatedCodeSnippets(relatedSnippets)
                    .conversationId(taskId)
                    .build();

        } catch (Exception e) {
            log.error("回答问题失败: {}, 任务ID: {}", e.getMessage(), taskId, e);
            return QaResponse.builder()
                    .answer("抱歉，处理您的问题时出现了错误：" + e.getMessage())
                    .relatedCodeSnippets(new ArrayList<>())
                    .conversationId(taskId)
                    .build();
        }
    }

    /**
     * 搜索相关代码片段（简化版本，使用关键词匹配）
     */
    private List<QaResponse.CodeSnippet> searchRelatedCode(String taskId, String question) {
        List<QaResponse.CodeSnippet> snippets = new ArrayList<>();

        // 获取所有代码结构
        List<CodeStructureEntity> structures = codeStructureRepository.findByTaskId(taskId);

        // 简单的关键词匹配
        String questionLower = question.toLowerCase();
        
        for (CodeStructureEntity structure : structures) {
            String nameLower = structure.getName().toLowerCase();
            
            // 如果问题包含类名或包名，则认为相关
            if (questionLower.contains(nameLower) || 
                (structure.getPackageName() != null && 
                 questionLower.contains(structure.getPackageName().toLowerCase()))) {
                
                snippets.add(QaResponse.CodeSnippet.builder()
                        .filePath(structure.getFilePath())
                        .content(buildCodeSnippetContent(structure))
                        .score(0.8)
                        .build());

                if (snippets.size() >= 5) {
                    break;
                }
            }
        }

        // 如果没有找到精确匹配，返回前几个类
        if (snippets.isEmpty() && !structures.isEmpty()) {
            for (int i = 0; i < Math.min(3, structures.size()); i++) {
                CodeStructureEntity structure = structures.get(i);
                snippets.add(QaResponse.CodeSnippet.builder()
                        .filePath(structure.getFilePath())
                        .content(buildCodeSnippetContent(structure))
                        .score(0.5)
                        .build());
            }
        }

        return snippets;
    }

    /**
     * 构建代码片段内容
     */
    private String buildCodeSnippetContent(CodeStructureEntity structure) {
        StringBuilder content = new StringBuilder();
        content.append("// 文件: ").append(structure.getFilePath()).append("\n");
        content.append("// 包: ").append(structure.getPackageName()).append("\n");
        content.append(structure.getAccessModifier()).append(" ");
        content.append(structure.getStructureType()).append(" ");
        content.append(structure.getName()).append(" {\n");
        
        if (structure.getSummary() != null) {
            content.append("  // 摘要: ").append(structure.getSummary()).append("\n");
        }
        
        content.append("  // ... 代码行数: ").append(structure.getLineCount()).append("\n");
        content.append("}\n");
        
        return content.toString();
    }

    /**
     * 构建项目索引（用于向量搜索，简化版本）
     */
    public void buildProjectIndex(String taskId) {
        log.info("开始构建项目索引, 任务ID: {}", taskId);

        try {
            List<CodeStructureEntity> structures = codeStructureRepository.findByTaskId(taskId);
            List<QaIndexEntity> indexes = new ArrayList<>();

            for (CodeStructureEntity structure : structures) {
                // 为每个代码结构创建索引
                QaIndexEntity index = QaIndexEntity.builder()
                        .taskId(taskId)
                        .content(buildCodeSnippetContent(structure))
                        .contentType("code")
                        .filePath(structure.getFilePath())
                        .metadata("{\"structureType\":\"" + structure.getStructureType() + "\"}")
                        .build();

                indexes.add(index);
            }

            if (!indexes.isEmpty()) {
                qaIndexRepository.saveAll(indexes);
                log.info("项目索引构建完成, 索引数: {}", indexes.size());
            }

        } catch (Exception e) {
            log.error("构建项目索引失败", e);
        }
    }
}

